<!--
 * @Author: wjc
 * @Date: 2025-09-09 09:40:45
 * @LastEditors: wjc
 * @LastEditTime: 2025-10-16 11:17:28
 * @Description: 
-->
<template>
  <div class="basic-layout">
    <Sidebar
      :show="!userStore.preferences.sidebar.hidden && !route.meta.sidebarHidden"
      v-model:collapse="userStore.preferences.sidebar.collapsed"
      v-model:expand-on-hover="userStore.preferences.sidebar.expandOnHover"
      :header-height="0"
      :margin-top="50"
      :extra-width="224"
      :fixed-extra="userStore.preferences.sidebar.expandOnHover"
      :width="getSidebarWidth"
      theme="light"
      :z-index="202"
    >
      <LayoutMenu
        :accordion="userStore.preferences.navigation.accordion"
        :collapse="userStore.preferences.sidebar.collapsed"
        :collapse-show-title="userStore.preferences.sidebar.collapsedShowTitle"
        :default-active="sidebarActive"
        :menus="sidebarMenus"
        :rounded="true"
        :theme="sidebarTheme"
        mode="vertical"
        @open="handleMenuOpen"
        @select="handleMenuSelect"
      />
    </Sidebar>
    <div class="flex flex-1 flex-col overflow-hidden transition-all duration-300 ease-in">
      <div
        :class="[
          {
            'shadow-[0_16px_24px_hsl(var(--background))]': scrollY > 20,
          },
          SCROLL_FIXED_CLASS,
        ]"
        class="overflow-hidden transition-all duration-200"
        :style="headerWrapperStyle"
      >
        <Header v-show="!userStore.isFullContent && !userStore.preferences.header.hidden" />
        <Tabbar :style="tabbarStyle" />
      </div>
      <Content :id="ELEMENT_ID_MAIN_CONTENT" :style="contentStyle" />
    </div>
  </div>
</template>

<script setup lang="ts">
  import type { CSSProperties } from 'vue'

  import { LayoutMenu } from '#/layouts/components'
  import { useMixedMenu } from '#/layouts/components/menu/use-mixed-menu'
  import { useUserStore } from '#/stores/modules'
  import { SCROLL_FIXED_CLASS } from '@nice/hooks'
  import { ELEMENT_ID_MAIN_CONTENT } from '@nice/utils'
  import { useScroll } from '@vueuse/core'

  import Content from './components/content/index.vue'
  import Header from './components/header/index.vue'
  import Sidebar from './components/sidebar/index.vue'
  import Tabbar from './components/tabbar/index.vue'

  defineOptions({ name: 'BasicLayout' })

  const route = useRoute()
  const { y: scrollY } = useScroll(document)
  const userStore = useUserStore()
  const preferencesApp = computed(() => userStore.preferences.app)
  const preferencesSidebar = computed(() => userStore.preferences.sidebar)

  const headerWrapperStyle = computed((): CSSProperties => {
    return {
      height: '88px',
      left: '0px',
      position: 'fixed',
      top: '0px',
      width: '100%',
      'z-index': '201',
    }
  })

  const getSidebarWidth = computed(() => {
    let width = 0

    if (preferencesApp.value.isMobile) {
      width = preferencesSidebar.value.width
    } else if (userStore.preferences.sidebar.collapsed) {
      width = preferencesApp.value.isMobile ? 0 : preferencesSidebar.value.collapseWidth
    } else {
      width = preferencesSidebar.value.width
    }
    return width
  })
  const sidebarTheme = computed(() => {
    return userStore.preferences.theme.mode
  })

  const tabbarStyle = computed((): CSSProperties => {
    let width = ''
    let marginLeft = 0

    if (userStore.isSidebarHidden || route.meta.sidebarHidden) {
      width = '100%'
    } else {
      // 鼠标在侧边栏上时，且侧边栏展开时的宽度
      const onHoveringWidth = preferencesSidebar.value.expandOnHover
        ? preferencesSidebar.value.width
        : preferencesSidebar.value.collapseWidth

      // 设置 marginLeft，根据侧边栏是否折叠来决定
      marginLeft = preferencesSidebar.value.collapsed
        ? preferencesSidebar.value.collapseWidth
        : onHoveringWidth

      // 设置 tabbar 的宽度，计算方式为 100% 减去侧边栏的宽度
      width = `calc(100% - ${preferencesSidebar.value.collapsed ? getSidebarWidth.value : onHoveringWidth}px)`
    }
    return {
      marginLeft: `${marginLeft}px`,
      width,
    }
  })

  const headerWrapperHeight = computed(() => {
    let height = 38
    if (!userStore.isHeaderHidden) {
      height += 50
    }
    return height
  })
  const contentStyle = computed((): CSSProperties => {
    return {
      marginTop: userStore.isFullContent ? 0 : `${headerWrapperHeight.value}px`,
      paddingBottom: `0px`,
    }
  })

  const { handleMenuSelect, handleMenuOpen, sidebarActive, sidebarMenus } = useMixedMenu()
</script>

<style lang="scss" scoped>
  .basic-layout {
    @apply relative flex min-h-full w-full;
  }
</style>
